package com.ustc.hewei.rpc.server.register;

import com.alibaba.fastjson2.JSON;
import com.ustc.hewei.rpc.common.protocol.Service;
import com.ustc.hewei.rpc.server.ServiceObject;
import com.ustc.hewei.rpc.server.register.notify.NotifyRegister;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.annotation.Resource;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
* @description: redis的注册中心
* @author hewei
* @date 2022/7/26 19:26
* @version 1.0
*/

@Slf4j
public class RedisRegisterCenter extends DefaultServiceRegister implements ServiceRegister {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    private NotifyRegister notifyRegister;

    private Service service;

    public RedisRegisterCenter(int port, String protocol, NotifyRegister notifyRegister) {
        this.port = port;
        this.protocol = protocol;
        this.notifyRegister = notifyRegister;
    }

    /*
     * @description: 将服务保存到本地的map集合中，并且将服务地址注册进redis中
     * @param serviceObject 需要注册的服务
     * @author: hewei
     * @date: 2022/7/26 19:45
     **/
    @Override
    public void register(ServiceObject serviceObject) throws UnknownHostException {
        // 先在服务端本地的map集合中注册一下，当有客户端请求时就从map中取
        super.register(serviceObject);
        String serviceName = serviceObject.getName();
        service = new Service();
        service.setName(serviceObject.getClazz().getName()).setProtocol(protocol);
        String serviceAddress = InetAddress.getLocalHost().getHostAddress() + ":" + port;
        service.setAddress(serviceAddress);
        log.info("服务 {} 在 {} 提供服务", serviceName, serviceAddress);
        exportService(service);
    }

    /*
     * @description: 将服务注册到redis中，即对外暴露提供服务的接口
     * @param service 需要暴露的服务
     * @author: hewei
     * @date: 2022/7/26 19:46
     **/
    private void exportService(Service service) {
        String serviceName = service.getName();
        // redis键值
        String key = "rpc/" + serviceName + "/service";
        // 存放的提供服务的地址
        String value = JSON.toJSONString(service);
        stringRedisTemplate.opsForSet().add(key, value);
        log.info("服务 {} 已成功注册到redis注册中心，键为 {}", serviceName, key);
        // 通知注册中心
        notifyRegister.sendNotify(service);
    }
}
